package tk.mystudio.idc.service;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.Locale;

import javax.annotation.Resource;
import javax.persistence.Column;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.NoSuchMessageException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import tk.mystudio.idc.dao.IdcBusinessDao;
import tk.mystudio.idc.dao.IdcProcessTrackDao;
import tk.mystudio.idc.dao.UpdateInfoDao;
import tk.mystudio.idc.pojo.IdcBusiness;
import tk.mystudio.idc.pojo.IdcProcessTrack;
import tk.mystudio.idc.pojo.UpdateInfo;
import tk.mystudio.util.Order;
import tk.mystudio.util.Page;

@Service
@Transactional
public class IdcBusinessService implements ApplicationContextAware {
	private final Logger logger = LoggerFactory
			.getLogger(IdcBusinessService.class);

	@Resource
	private IdcBusinessDao idcBusinessDao;

	private ApplicationContext applicationContext;

	@Resource
	private IdcProcessTrackDao idcProcessTrackDao;

	@Resource
	private UpdateInfoDao updateInfoDao;

	public void setIdcBusinessDao(IdcBusinessDao idcBusinessDao) {
		this.idcBusinessDao = idcBusinessDao;
	}

	public void setIdcProcessTrackDao(IdcProcessTrackDao idcProcessTrackDao) {
		this.idcProcessTrackDao = idcProcessTrackDao;
	}

	public void setUpdateInfoDao(UpdateInfoDao updateInfoDao) {
		this.updateInfoDao = updateInfoDao;
	}

	private String getMessage(String key) {
		String message = key;
		try {
			message = applicationContext.getMessage(key, null, Locale.CHINA);
		} catch (NoSuchMessageException e) {
			logger.error(e.getMessage());
		}
		return message;
	}

	private IdcBusiness writeUpdateLogger(IdcBusiness newIdc, IdcBusiness oldIdc)
			throws Exception {
		Field[] oldFields = oldIdc.getClass().getDeclaredFields();
		Field[] newFields = oldIdc.getClass().getDeclaredFields();
		for (int i = 0; i < oldFields.length; i++) {
			Field oldField = oldFields[i];
			Column aColumn = oldField.getAnnotation(Column.class);
			if (aColumn == null) {
				continue;
			}
			Field newField = newFields[i];
			oldField.setAccessible(true);
			newField.setAccessible(true);
			Object oldValue = oldField.get(oldIdc);
			Object newValue = newField.get(newIdc);
			// oldField.getName();
			if (oldValue != null && !oldValue.equals(newValue)) {
				String name = aColumn.name();
				UpdateInfo updateInfo = new UpdateInfo();
				updateInfo.setIdcBusinessId(oldIdc.getId());
				updateInfo.setNewValue((String) newValue);
				updateInfo.setOldValue((String) oldValue);
				updateInfo.setUpdateDate(new Date());
				updateInfo.setUpdatedColumn(name);
				updateInfo.setUpdatedColumnName(getMessage(name));
				updateInfoDao.save(updateInfo);

				oldField.set(oldIdc, newValue);
			}
		}

		return oldIdc;

	}

	/**
	 * 新增保存业务单
	 * 
	 * @param idcBusiness
	 * @return
	 */
	@Transactional
	public IdcBusiness saveIdcBusiness(IdcBusiness idcBusiness) {
		return idcBusinessDao.save(idcBusiness);
	}

	/**
	 * 
	 * @param idcBusinessId
	 *            进行审批的业务单编号
	 * @param idcBusinessStatus
	 *            审批的状态
	 * @return
	 */
	@Transactional
	public IdcBusiness approve(Integer idcBusinessId, Integer idcBusinessStatus) {
		IdcBusiness idcBusiness = idcBusinessDao.get(idcBusinessId);
		Integer oldIdcBsinessStatus = idcBusiness.getStatus();
		idcBusiness.setStatus(idcBusinessStatus);
		idcBusiness = idcBusinessDao.update(idcBusiness);

		IdcProcessTrack idcProcessTrack = new IdcProcessTrack();
		idcProcessTrack.setIdcBusinessId(idcBusinessId);
		idcProcessTrack.setIdcStatus(idcBusinessStatus);
		idcProcessTrack.setProcessDate(new Date());
		idcProcessTrack = idcProcessTrackDao.save(idcProcessTrack);

		logger.info("处理者：" + 1 + " 将IDC申请单的状态由 " + oldIdcBsinessStatus
				+ " 更新为 " + idcBusinessStatus);
		return idcBusiness;
	}

	/**
	 * 更新Idc业务单
	 * 
	 * @param idcBusiness
	 * @return
	 */
	@Transactional
	public IdcBusiness updateIdcBusiness(IdcBusiness idcBusiness) {
		IdcBusiness oldIdcBusiness = idcBusinessDao.get(idcBusiness.getId());

		try {
			oldIdcBusiness = writeUpdateLogger(idcBusiness, oldIdcBusiness);
			oldIdcBusiness = idcBusinessDao.update(oldIdcBusiness);
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return oldIdcBusiness;
	}

	/**
	 * 通过业务单的idc查找业务单
	 * 
	 * @param idcBusinessId
	 * @return
	 */
	public IdcBusiness getIdcBusinessById(Integer idcBusinessId) {

		IdcBusiness idcBusiness = idcBusinessDao.get(idcBusinessId);

		return idcBusiness;
	}

	/**
	 * 查询指定状态的idc业务单
	 * 
	 * @param idcStatus
	 * @param page
	 * @param order
	 * @return
	 */
	public Page<IdcBusiness> getPageByStatus(Integer idcStatus,
			Page<IdcBusiness> page, Order order) {
		IdcBusiness idcBusiness = new IdcBusiness();
		idcBusiness.setStatus(idcStatus);
		page = idcBusinessDao.listByPage(idcBusiness, page,
				new Order[] { order });
		return page;
	}

	/**
	 * 以指定条件分布查询Idc业务单
	 * 
	 * @param idcBusiness
	 * @param page
	 * @return
	 */
	public Page<IdcBusiness> getListByPage(IdcBusiness idcBusiness,
			Page<IdcBusiness> page) {
		page = idcBusinessDao.listByPage(idcBusiness, page,
				new Order[] { Order.descend("id") });
		return null;
	}

	@Override
	public void setApplicationContext(ApplicationContext app)
			throws BeansException {
		applicationContext = app;
	}
}
